from flask import Blueprint, request, jsonify, current_app
from werkzeug.utils import secure_filename
from app.services.aliyun_oss import AliyunOSS
import os
import uuid

upload_bp = Blueprint('upload', __name__, url_prefix='/api/upload')


def compress_image(file, max_width=1000):
    """
    压缩图片文件

    参数:
    - file: 上传的文件对象
    - max_width: 图片最大宽度，默认1000

    返回:
    - 压缩后的文件对象
    """
    from PIL import Image
    import io

    # 如果不是图片则直接返回原文件
    if not file.content_type.startswith('image/'):
        return file

    try:
        # 打开图片
        img = Image.open(file.stream)

        # 如果宽度超过最大宽度，按比例缩小
        if img.width > max_width:
            ratio = max_width / float(img.width)
            new_height = int(float(img.height) * ratio)
            img = img.resize((max_width, new_height), Image.LANCZOS)

        # 如果是PNG则转换为JPG
        if img.format == 'PNG':
            img = img.convert('RGB')

        # 设置压缩质量(85%)
        output = io.BytesIO()
        img.save(output, format='JPEG', quality=85)
        output.seek(0)

        # 创建新的文件对象
        from werkzeug.datastructures import FileStorage
        compressed_file = FileStorage(
            stream=output,
            filename=file.filename,
            content_type='image/jpeg',
            name=file.name
        )

        return compressed_file

    except Exception as e:
        current_app.logger.error(f"图片压缩失败: {str(e)}")
        return file


@upload_bp.route('/file', methods=['POST'])
def upload_file():
    """
    上传文件到阿里云OSS

    请求参数:
    - file: 要上传的文件
    - folder: (可选) OSS中的文件夹路径，默认为'uploads'

    返回:
    - url: 文件的URL
    - object_name: OSS对象名称
    """
    # 检查是否有文件
    if 'file' not in request.files:
        return jsonify({'error': '没有文件'}), 400

    file = request.files['file']
    # 压缩图片
    file = compress_image(file)

    # 检查文件名是否为空
    if file.filename == '':
        return jsonify({'error': '没有选择文件'}), 400

    # 获取请求中的文件夹参数，默认为'uploads'
    folder = request.form.get('folder', 'uploads')

    try:
        # 创建OSS客户端
        oss_client = AliyunOSS()

        # 上传文件
        result = oss_client.upload_file(file, folder=folder)
        print(result)
        # 返回文件URL和对象名称
        return jsonify({
            'code': 200,
            'data': {
                'url': result['url'],
                'object_name': result['object_name']
            }
        })
    except Exception as e:
        current_app.logger.error(f"文件上传失败: {str(e)}")
        return jsonify({'error': f'文件上传失败: {str(e)}'}), 500

@upload_bp.route('/delete', methods=['POST'])
def delete_file():
    """
    删除OSS上的文件

    请求参数:
    - object_name: OSS对象名称

    返回:
    - success: 是否删除成功
    """
    # 获取对象名称
    object_name = request.json.get('object_name')

    if not object_name:
        return jsonify({'error': '缺少对象名称参数'}), 400

    try:
        # 创建OSS客户端
        oss_client = AliyunOSS()

        # 删除文件
        success = oss_client.delete_file(object_name)

        if success:
            return jsonify({'success': True}), 200
        else:
            return jsonify({'error': '文件删除失败'}), 500
    except Exception as e:
        current_app.logger.error(f"文件删除失败: {str(e)}")
        return jsonify({'error': f'文件删除失败: {str(e)}'}), 500

@upload_bp.route('/signed-url', methods=['GET'])
def get_signed_url():
    """
    获取带签名的临时访问URL

    请求参数:
    - object_name: OSS对象名称
    - expires: (可选) URL有效期（秒），默认1小时

    返回:
    - url: 带签名的临时访问URL
    """
    # 获取对象名称和过期时间
    object_name = request.args.get('object_name')
    expires = request.args.get('expires', 3600, type=int)

    if not object_name:
        return jsonify({'error': '缺少对象名称参数'}), 400

    try:
        # 创建OSS客户端
        oss_client = AliyunOSS()

        # 获取签名URL
        url = oss_client.get_signed_url(object_name, expires)

        return jsonify({'url': url}), 200
    except Exception as e:
        current_app.logger.error(f"获取签名URL失败: {str(e)}")
        return jsonify({'error': f'获取签名URL失败: {str(e)}'}), 500
